#include "resources.h"
#include <logger/logger.h>
#include <cassert>
#include <iomanip>
#include <sstream>

namespace cores
{
    namespace common
    {
        uint16_t Resources::crc16(const uint8_t *data, const int &size)
        {
            const uint16_t polynomial = 0xa001; //  使用多项式
            uint16_t crc = 0x0000;              //  初始CRC值
            uint16_t flag;

            for (auto current_byte = 0; current_byte < size; current_byte++)
            {
                crc ^= (data[current_byte] << 8);

                for (uint8_t i = 0; i < 8; i++)
                {
                    flag = crc & 0x8000;
                    crc <<= 1;
                    if (flag)
                        crc ^= polynomial;
                }
            }

            return crc;
        }

        int Resources::transData2TokenChar(uint8_t *buffer, const int &size, const OilTransReq &model, const uint32_t &now_time)
        {
            assert(size >= 18);

            auto pos = valueToHexChar<uint16_t>(model.lora_id, buffer, size); 

            // 数据流头标志
            buffer[pos++] = 0xFE; // 协议头
            buffer[pos++] = 0x0C; // 协议长度低位
            buffer[pos++] = 0x00; // 协议长度高位
            buffer[pos++] = 0x01; // 指令 1字节

            // 写入lora id
            auto l = valueToHexChar<uint16_t>(model.lora_id, buffer + pos, size - pos);
            pos += l;

            // 写入枪号
            l = valueToHexChar<uint8_t>(model.nozzle_code, buffer + pos, size - pos);
            pos += l;

            // 写入时间戳
            l = valueToHexChar<uint32_t>(now_time, buffer + pos, size - pos);
            pos += l;

            // 写入交易数据编号
            l = valueToHexChar<uint16_t>(model.current_req_num, buffer + pos, size - pos);
            pos += l;

            uint16_t crc = Resources::crc16(buffer + 5, pos - 5);
            l = valueToHexChar<uint16_t>(crc, buffer + pos, size - pos);
            pos += l;

            return pos;
        }

        string Resources::bytesToHexStr(const uint8_t* buffer, const int& size)
        {
            stringstream ss;
            ss << hex;
            for (auto i = 0; i < size; i++)
            {
                if (i > 0)
                    ss << " ";
                ss << setw(2) << setfill('0') << int(buffer[i]);                
            }
            return ss.str();
        }
    }
}